<template>
  <div class="scanner-container">
    <div v-show="!isLoading">
      <video poster="data:image/gif,AAAA" ref="scanner"></video>
      <div class="overlay-element"></div>
      <div class="laser"></div>
    </div>
    <audio id="scanAudioTip" controls="controls" hidden :src="audioTip" ref="audio"></audio>
  </div>
</template>
      
<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import { BrowserMultiFormatReader, Exception } from "@zxing/library"
import audioTipFile from '@/assets/media/tishi.mp3'

// 定义 props
const props = defineProps({
  width: String,
  height: String,
  paused: {
    type: Boolean,
    default: false
  }
})

// 定义 emits
const emit = defineEmits(['decode', 'loaded'])

// 响应式数据
const audioTip = ref(audioTipFile)
const isLoading = ref(true)
const scanner = ref(null)
const audio = ref(null)
const codeReader = new BrowserMultiFormatReader()

// 检查浏览器支持
const isMediaStreamAPISupported = navigator && 
  navigator.mediaDevices && 
  'enumerateDevices' in navigator.mediaDevices

// 方法
const play = () => {
  codeReader.decodeFromVideoDevice(undefined, scanner.value, (result, err) => {
    if (result) {
      emit('decode', result.text)
      playTip().catch(console.error)
    }
  })
}

const stopScanning = () => {
  codeReader.reset()
}

const playTip = async () => {
  try {
    if (audio.value) {
      audio.value.currentTime = 0
      await audio.value.play()
    }
  } catch (error) {
    console.error('播放提示音失败:', error)
  }
}

// 生命周期钩子
onMounted(() => {
  if (!isMediaStreamAPISupported) {
    throw new Exception('Media Stream API is not supported')
  }
  if (!props.paused) {
    play()
  }
  scanner.value.oncanplay = (event) => {
    isLoading.value = false
    emit('loaded')
  }
})

// 监听暂停状态
watch(() => props.paused, (newVal) => {
  if (newVal) {
    stopScanning()
  } else {
    play()
  }
})

onBeforeUnmount(() => {
  stopScanning()
})

// 暴露方法给父组件
defineExpose({
  play,
  stopScanning
})
</script>

<style scoped>
video {
  max-width: 100%;
  max-height: 100%;
}
.scanner-container {
  position: relative;
}
.overlay-element {
  position: absolute;
  top: 0;
  width: 100%;
  height: 99%;
  background: rgba(30, 30, 30, 0.5);
  -webkit-clip-path: polygon(
    0% 0%,
    0% 100%,
    20% 100%,
    20% 20%,
    80% 20%,
    80% 80%,
    20% 80%,
    20% 100%,
    100% 100%,
    100% 0%
  );
  clip-path: polygon(
    0% 0%,
    0% 100%,
    20% 100%,
    20% 20%,
    80% 20%,
    80% 80%,
    20% 80%,
    20% 100%,
    100% 100%,
    100% 0%
  );
}
.laser {
  width: 60%;
  margin-left: 20%;
  background-color: tomato;
  height: 1px;
  position: absolute;
  top: 40%;
  z-index: 2;
  box-shadow: 0 0 4px red;
  -webkit-animation: scanning 2s infinite;
  animation: scanning 2s infinite;
}
@-webkit-keyframes scanning {
  50% {
    -webkit-transform: translateY(75px);
    transform: translateY(75px);
  }
}
@keyframes scanning {
  50% {
    -webkit-transform: translateY(75px);
    transform: translateY(75px);
  }
}
</style>